home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Pascal / Snippets / PNL Libraries / MyNotifier.p < prev    next >
Text File  |  1997-01-17  |  6KB  |  247 lines

  1. unit MyNotifier;
  2.  
  3. { Derived from <jholt@adobe.COM> Joe Holt's StartupError code as posted }
  4. { to comp.sys.mac.programmer in May 1991 }
  5.  
  6. { Notification Manager messages }
  7.  
  8. { History: }
  9. {   jhh 18 jun 90 -- response to news posting }
  10. {   pnl 29 may 91 -- Converted to pascal to be used in an application }
  11.  
  12. interface
  13.  
  14.     uses
  15.         Types, Memory;
  16.  
  17.     const
  18.         mark_app = 1;
  19.         mark_none = 0;
  20.         notify_no_string = 0;
  21.         notify_use_str = 0;
  22.         notify_no_sicn = 0;
  23.         notify_mark = true;
  24.         notify_no_mark = false;
  25.         notify_sound = true;
  26.         notify_no_sound = false;
  27.         notify_no_display = 0;
  28.  
  29.     procedure StartupNotifier;
  30.     procedure NotifyH (mark: integer; sound: Handle; sicn: Handle; str: StringPtr; display_time: longint);
  31.     procedure Notify (mark, sound: boolean; sicn_id, sicn_index, str_id, str_index: integer; display_time: longint);
  32. { mark - mark the current application }
  33. { sound - play sysbeep }
  34. { sicn_id, sicn_index - SICN id to rotate with the apple & index (<1 -> 1)   OR 0&0 for no sicn }
  35. { str_id, str_index - STR# id & index    OR    STR id & 0    OR    0 & 0 }
  36.     procedure UnNotify;
  37. { Call this to get rid of the notification }
  38.  
  39.     var
  40.         notify_finished, notify_outstanding: boolean;
  41.         time_to_unnotify: longint;
  42.  
  43. implementation
  44.  
  45.     uses
  46.         Types, Notification, GestaltEqu, Icons, OSUtils, TextUtils, Resources, Events, 
  47.         MyStartup, MySystemGlobals, MyMemory, MyAssertions;
  48.  
  49.     const
  50.         sicn_size = 32;
  51.         T_NMInstall = $A05E;
  52.         T_Unimplemented = $A89F;
  53.  
  54.     type
  55.         NMRecPtrPtr = ^NMRecPtr;
  56.         booleanPtr = ^boolean;
  57.  
  58. {$ifc do_debug}
  59.     var
  60.         startup_check: integer;
  61. {$endc}
  62.  
  63.     var
  64.         current_note: NMRecPtr;
  65.  
  66.     var
  67.         gMyResponseProc : UniversalProcPtr;
  68.         
  69. { handles must be non-purgeable, but may be unlocked }
  70.  
  71.     procedure MyResponse (note: NMRecPtr);
  72.     begin
  73.         booleanPtr(note^.nmRefCon)^ := true;
  74.     end;
  75.  
  76.     procedure UnNotify;
  77.         var
  78.             oe: OSErr;
  79.     begin
  80.         if current_note <> nil then begin
  81.             oe := NMRemove(current_note);
  82.             with current_note^ do begin
  83.                 if nmStr <> nil then begin
  84.                     MDisposePtr( nmStr );
  85.                 end;
  86.                 if nmIcon <> nil then begin
  87.                     MDisposeHandle(nmIcon);
  88.                 end;
  89.             end;
  90.             MDisposePtr( current_note );
  91.         end;
  92.         notify_finished := false;
  93.         notify_outstanding := false;
  94.         time_to_unnotify := maxLongInt;
  95.     end;
  96.  
  97.     procedure NotifyH (mark: integer; sound: Handle; sicn: Handle; str: StringPtr; display_time: longint);
  98.         var
  99.             error: boolean;
  100.             oe: OSErr;
  101.     begin
  102.         AssertDidStartup( startup_check );
  103.         UnNotify;            { Clear outstanding notify }
  104.         if NGetTrapAddress(T_NMInstall, OSTrap) = NGetTrapAddress(T_Unimplemented, ToolTrap) then begin
  105.             SysBeep(1);   { Best we can do I guess.  Could put up the dialog box maybe?...}
  106.         end else begin
  107.             if MNewPtr( current_note, SizeOf(NMRec) ) <> noErr then begin
  108.                 SysBeep(1);   { Can't do much else if there isnt even room for this! }
  109.             end else begin
  110.                 with current_note^ do begin
  111.                     qType := nmType;
  112.                     error := false;
  113.                     booleanPtr(nmRefCon) := @notify_finished;
  114.                     nmMark := mark;
  115.                     nmStr := str;
  116.                     nmIcon := sicn;
  117.                     nmSound := sound;
  118.                     nmResp := gMyResponseProc;
  119.                 end;
  120.                 oe := NMInstall(current_note);
  121.                 if oe <> noErr then begin
  122.                     current_note := nil;
  123.                     SysBeep(1);
  124.                 end else begin
  125.                     notify_outstanding := true;
  126.                     if display_time > 0 then begin
  127.                         time_to_unnotify := TickCount + display_time;
  128.                     end;
  129.                 end;
  130.             end;
  131.         end;
  132.     end;
  133.  
  134.     procedure Notify (mark, sound: boolean; sicn_id, sicn_index, str_id, str_index: integer; display_time: longint);
  135.         var
  136.             errorText: Str255;
  137.             sh: StringHandle;
  138.             sicnH: Handle;
  139.             error: boolean;
  140.             nmMark: integer;
  141.             nmStr: StringPtr;
  142.             nmIcon: Handle;
  143.             nmSound: Handle;
  144.             gv: longint;
  145.     begin
  146.         Assert( (sicn_id >= 0) & (sicn_index > 0) & (str_id >= 0) & (str_index >= 0) & (display_time >= 0) );
  147.         error := false;
  148.         if mark then begin
  149.             nmMark := 1;
  150.         end else begin
  151.             nmMark := 0;
  152.         end;
  153.         nmStr := nil;
  154.         if str_id <> notify_no_string then begin
  155.             if str_index > 0 then begin
  156.                 GetIndString(errorText, str_id, str_index);
  157.             end else begin
  158.                 errorText := '';
  159.                 sh := GetString(str_id);
  160.                 if sh <> nil then begin
  161.                     if sh^ <> nil then begin
  162.                         errorText := sh^^;
  163.                     end;
  164.                     ReleaseResource(Handle(sh));
  165.                 end;
  166.             end;
  167.             if errorText = '' then begin
  168.                 error := true;
  169.             end else begin
  170.                 if MNewPtr( nmStr, length(errorText) + 1 ) <> noErr then begin
  171.                     error := true;
  172.                 end else begin
  173.                     nmStr^ := errorText;
  174.                 end;
  175.             end;
  176.         end;
  177.         nmIcon := nil;
  178.         if sicn_id <> notify_no_sicn then begin
  179.  
  180.             nmIcon := nil;
  181.             if (Gestalt(gestaltSystemVersion, gv) = noErr) & (gv >= $0700) then begin
  182.                 if GetIconSuite(nmIcon, sicn_id, svAllSmallData) <> noErr then begin
  183.                     nmIcon := nil;
  184.                 end;
  185.             end;
  186.             if nmIcon = nil then begin
  187.                 Assert( sicn_index > 0 );
  188.                 if sicn_index < 1 then begin
  189.                     sicn_index := 1;
  190.                 end;
  191.                 sicn_index := (sicn_index - 1) * sicn_size;   { 1-based, like STR# }
  192.                 sicnH := GetResource('SICN', sicn_id);
  193.                 HNoPurge(sicnH);
  194.                 if sicnH = nil then begin
  195.                     error := true;
  196.                 end else begin
  197.                     if MNewHandle( nmIcon, sicn_size ) <> noErr then begin
  198.                         error := true;
  199.                     end else if GetHandleSize(sicnH) < sicn_index + sicn_size then begin
  200.                         error := true;
  201.                     end else begin
  202.                         BlockMoveData(Ptr(longint(sicnH^) + sicn_index), nmIcon^, sicn_size);
  203.                     end;
  204.                     ReleaseResource(sicnH);
  205.                 end;
  206.             end;
  207.         end;
  208.         if sound or error then begin
  209.             nmSound := Handle(-1);
  210.         end else begin
  211.             nmSound := nil;
  212.         end;
  213.         NotifyH(nmMark, nmSound, nmIcon, nmStr, display_time);
  214.     end;
  215.  
  216.     function InitNotifier(var msg: integer): OSStatus;
  217.     begin
  218. {$unused(msg)}
  219.         DidStartup( startup_check );
  220.         current_note := nil;
  221.         notify_finished := false;
  222.         notify_outstanding := false;
  223.         time_to_unnotify := maxLongInt;
  224.         gMyResponseProc := NewNMProc(MyResponse);
  225.         InitNotifier := noErr;
  226.     end;
  227.  
  228.     procedure FinishNotifier;
  229.     begin
  230.         if current_note <> nil then begin
  231.             UnNotify;
  232.         end;
  233.     end;
  234.  
  235.     procedure IdleNotifier;
  236.     begin
  237.         if (notify_finished and InForeground) or (TickCount > time_to_unnotify) then begin
  238.             UnNotify;
  239.         end;
  240.     end;
  241.  
  242.     procedure StartupNotifier;
  243.     begin
  244.         SetStartup(InitNotifier, IdleNotifier, 10, FinishNotifier);
  245.     end;
  246.     
  247. end.